package com.repast.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.repast.common.Const;
import com.repast.common.ServerResponse;
import com.repast.dao.AddDishMapper;
import com.repast.dao.AddressMapper;
import com.repast.dao.AppointMapper;
import com.repast.dao.DeskMapper;
import com.repast.dao.DeskTimeMapper;
import com.repast.dao.FoodsMapper;
import com.repast.dao.OrderProcessMapper;
import com.repast.dao.OrdersItemMapper;
import com.repast.dao.OrdersMapper;
import com.repast.dao.RestaurantInfoMapper;
import com.repast.pojo.AddDish;
import com.repast.pojo.Address;
import com.repast.pojo.Appoint;
import com.repast.pojo.Desk;
import com.repast.pojo.DeskTime;
import com.repast.pojo.Foods;
import com.repast.pojo.OrderProcess;
import com.repast.pojo.Orders;
import com.repast.pojo.OrdersItem;
import com.repast.pojo.RestaurantInfo;
import com.repast.service.IOrdersService;
import com.repast.utils.CalculateDateUtils;
import com.repast.utils.DateUtils;
import com.repast.utils.PackagePayInfo;
import com.repast.vo.AddDishItemVo;
import com.repast.vo.OrdersAndItemsVo;
import com.repast.vo.OrdersItemVo;
import com.repast.vo.OrdersVo;
import com.repast.vo.PayMoneyInfo;


@Service
public class OrdersServiceImpl implements IOrdersService {

	@Autowired
	private OrdersMapper ordersMapper;
	@Autowired
	private AddressMapper addressMapper;
	@Autowired
	private OrdersItemMapper ordersItemMapper;
	@Autowired
	private DeskTimeMapper deskTimeMapper;
	@Autowired
	private AppointMapper appointMapper;
	@Autowired
	private RestaurantInfoMapper rsMapper;
	@Autowired
	private AddDishMapper addDishMapper;
	@Autowired
	private FoodsMapper foodsMapper;
	@Autowired
	private OrderProcessMapper orderProcessMapper;
	@Autowired
	private DeskMapper deskMapper;


	public ServerResponse submitOrder(OrdersVo ordersVo) throws Exception {
		
		Orders orders = new Orders();
		// 封装openid
		orders.setOpenid(ordersVo.getOpenid());
		// 先随机生成订单号
		String ordersNum = new SimpleDateFormat("MMyyyyddHHmmssSSS").format(new Date());
		orders.setOrdersNum(ordersNum);
		// 封装订单的创建时间,和更新时间
		orders.setOrdersCreatetime(DateUtils.formatDateTime(new Date(), "long"));
		orders.setOrdersUpdateTime(DateUtils.formatDateTime(new Date(), "long"));
		// 封装订单选择的口味
		orders.setOrdersTastes(ordersVo.getOrdersTastes());
		// 封装订单的大类型
		int ordersType = ordersVo.getOrdersType();
		orders.setOrdersType(ordersType);
		// 封装订单的状态,初始状态默认堂食未付款1
		orders.setOrdersTypeStatus(Const.OrdersTypeStatus.WAIT_PAY);
		// 不是外卖类型不需要关联收货地址,只有外卖才需要封装收货地址:0,外卖,1,堂食,2,预约,3外带
		if (ordersType == 0) {
			// 封装订单收货信息
			List<Address> addressList = addressMapper.selectDeliveryInfoByOpenid(ordersVo.getOpenid(),
					Const.AddressType.DEFAULT_ADDRESS);
			if (addressList.size() != 0) {
				orders.setAddressId(addressList.get(0).getAddressId());
			} else {
				return ServerResponse.createByErrorCodeMessage(Const.ADDRESS_SYSTEM_ERROR, "系统异常,获取不到默认地址!");
			}
		}
		// 封装订单的总额
		orders.setOrdersTotal(ordersVo.getOrdersTotal());
		
		// 封装桌子id
		int deskId = ordersVo.getDeskId();
		// 如果是堂食/预约就封装桌子,外卖和外带不封装桌子
		if (deskId != -1) {
			orders.setDeskId(ordersVo.getDeskId());
		}
		int insertResult = ordersMapper.insert(orders);
		if (insertResult == 0) {
			return ServerResponse.createByErrorCodeMessage(Const.CREATE_ORDERS_FAIL, "订单生成失败");
		}
		
		//封装订单流程信息
		OrderProcess orderProcess = new OrderProcess();
		orderProcess.setOrdersId(orders.getOrdersId());
		orderProcess.setOrdersType(ordersType);
		orderProcess.setOrdersProcessStatus(Const.OrdersTypeStatus.WAIT_PAY);
		orderProcess.setOrdersStatusTime(DateUtils.formatDateTime(new Date(), "middle"));
		int insertOrderProcess = orderProcessMapper.insert(orderProcess);
		if(insertOrderProcess==0){
			return ServerResponse.createByErrorMessage("订单流程更新失败");
		}
		
		
		//把订单的id封装到appoint表中去
		Integer appointId = ordersVo.getAppointId();
		if(appointId!=-1){
			Appoint appoint = appointMapper.selectByPrimaryKey(appointId);
			appoint.setOrdersId(orders.getOrdersId());
			appoint.setAppointCreateTime(DateUtils.formatDateTime(new Date(), "long"));
			appoint.setAppointUpdateTime(DateUtils.formatDateTime(new Date(), "long"));
			int insertAppoint = appointMapper.updateByPrimaryKeySelective(appoint);
			if(insertAppoint==0){
				return ServerResponse.createByErrorCodeMessage(Const.APPOINT_ADD_ORDERS_FAIL, "预约添加订单id失败");
			}
		}
		// 桌子deskTime等支付成功后再标志
		// 封装订单小项
		
		//给订单项封装订单id
		//List<Orders> ordersList = ordersMapper.selectOrdersByOrdersNum(ordersNum);
		//int ordersId = ordersList.get(0).getOrdersId();
		List<OrdersItemVo> ordersItemVoList = ordersVo.getOrdersItemList();
		for (OrdersItemVo ordersItemVo : ordersItemVoList) {
			if (null != ordersItemVo) {
				OrdersItem ordersItem = new OrdersItem();
				ordersItem.setFoodsId(ordersItemVo.getFoodsId());
				ordersItem.setOrdersItemNum(ordersItemVo.getOrdersItemNum());
				ordersItem.setOrdersItemSubtotal(ordersItemVo.getOrdersItemSubtotal());
				ordersItem.setOrdersId(orders.getOrdersId());
				//String time = DateUtils.formatDateTime(new Date(), "middle");
				ordersItem.setOrdersItemCreateTime(DateUtils.formatDateTime(new Date(), "long"));
				ordersItem.setOrdersItemUpdateTime(DateUtils.formatDateTime(new Date(), "long"));
				int insert = ordersItemMapper.insert(ordersItem);
				if (insert == 0) {
					return ServerResponse.createByErrorCodeMessage(Const.CREATE_ORDERSITM_FAIL, "订单项生成失败");
				}
			}
		}
		
		PayMoneyInfo info = PackagePayInfo.packageMessage(ordersNum, ordersVo.getOpenid(), ordersVo.getOrdersTotal());
		return ServerResponse.createBySuccess(info);
	}

	public ServerResponse updateOrders(String ordersNum,Integer appointId) {
		List<Orders> ordersList = ordersMapper.selectOrdersByOrdersNum(ordersNum);
		if (ordersList.size() == 0) {
			return ServerResponse.createByErrorCodeMessage(Const.ORDERS_NUM_ERROR, "订单号异常,修改订单状态失败");
		}
		// 修改订单状态,不同的类型给的状态不一样,0,外卖,1,堂食,2,预约,3外带
		int ordersType = ordersList.get(0).getOrdersType();
		if (ordersType == 0) {
			// 外卖类型,付款完成为待接单状态(后台有自动接单功能,自动接单后为待发货状态),2
			ordersList.get(0).setOrdersTypeStatus(Const.OrdersTypeStatus.WAIT_RECEIVE);
		}
		if (ordersType == 1) {
			// 堂食类型,付款完成后为待上菜状态,7
			ordersList.get(0).setOrdersTypeStatus(Const.OrdersTypeStatus.WAIT_RECEIVE);
		}
		if (ordersType == 2) {
			//预约
			//把订单号封装到appoint里面
			if(appointId!=-1){
				Appoint appoint = appointMapper.selectByPrimaryKey(appointId);
				appoint.setOrdersId(ordersList.get(0).getOrdersId());
				appointMapper.updateByPrimaryKeySelective(appoint);
			}
			// 预约类型(预约点餐),付款完成为已预约状态,9
			ordersList.get(0).setOrdersTypeStatus(Const.OrdersTypeStatus.EVER_APPOINT);
		}
		if (ordersType == 3) {
			// 外带类型(预约点餐),付款完成为待打包状态,8
			ordersList.get(0).setOrdersTypeStatus(Const.OrdersTypeStatus.WAIT_RECEIVE);
		}
		ordersList.get(0).setOrdersUpdateTime(DateUtils.formatDateTime(new Date(), "long"));
		int updateOrders = ordersMapper.updateByPrimaryKeySelective(ordersList.get(0));
		if(updateOrders==0){
			return ServerResponse.createByErrorCodeMessage(Const.ORDERS_UPDATE_FAIL, "订单更新失败");
		}
		//如果不是预约,就封装桌子预约的时间,因为预约的时间已在预约的时候封装,不能重复封装
		if(ordersType == 1){
			// 封装deskTime被使用的开始和结束时间
			DeskTime deskTime = new DeskTime();
			deskTime.setDeskId(ordersList.get(0).getDeskId());
			// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			String start = DateUtils.formatDateTime(new Date(), "middle");
			// 封装开始时间
			deskTime.setDeskTimeStartTime(start);
			// 封装结束时间,当前时间加30分钟,直接返回字符串
			String end = CalculateDateUtils.addMinutes(30);
			deskTime.setDeskTimeEndTime(end);
			int insertDeskTime = deskTimeMapper.insert(deskTime);
			if (insertDeskTime == 0) {
				return ServerResponse.createByErrorCodeMessage(Const.SET_DESK_TIME_FAIL, "封装桌子使用时间失败");
			}
		}
		return ServerResponse.createBySuccess();
	}

	public ServerResponse selectOrdersList(String openid, Integer pageNum, Integer pageSize) {
		PageHelper.startPage(pageNum, pageSize);
		PageHelper.orderBy("orders_createtime desc");
		List<OrdersAndItemsVo> ordersAndItemsVo =new ArrayList<OrdersAndItemsVo>();
		List<Orders> list = ordersMapper.selectOrdersList(openid);
		for (Orders orders : list) {
			if(null!=orders){
				OrdersAndItemsVo newOrders = new OrdersAndItemsVo();
				newOrders.setOrders(orders);
				Integer deskId = orders.getDeskId();
				if(deskId!=null){
					Desk desk = deskMapper.selectByPrimaryKey(deskId);
					newOrders.setDeskName(desk.getDeskName());
					newOrders.setDeskType(desk.getDeskType());
				}
				
				//封装订单项list和加菜list
				List<OrdersItem> ordersItemList = ordersItemMapper.selectOrderItemListByOrdersId(orders.getOrdersId());
				for (OrdersItem ordersItem : ordersItemList) {
					OrdersItemVo ordersItemVo = new OrdersItemVo();
					Foods foods = foodsMapper.selectByPrimaryKey(ordersItem.getFoodsId());
					ordersItemVo.setFoodsId(ordersItem.getFoodsId());
					ordersItemVo.setFoodsName(foods.getFoodsName());
					ordersItemVo.setFoodsPrice(foods.getFoodsPrice());
					ordersItemVo.setFoodsUrl(foods.getFoodsUrl());
					ordersItemVo.setOrdersItemNum(ordersItem.getOrdersItemNum());
					ordersItemVo.setOrdersItemSubtotal(ordersItem.getOrdersItemSubtotal());
					newOrders.getList().add(ordersItemVo);
				}
				//加菜小项信息
				List<AddDish> addDishList = addDishMapper.selectAddDishItemListByOrdersId(orders.getOrdersId());
				for (AddDish addDish : addDishList) {
					AddDishItemVo addDishItemVo = new AddDishItemVo();
					Foods foods = foodsMapper.selectByPrimaryKey(addDish.getFoodsId());
					addDishItemVo.setFoodsId(foods.getFoodsId());
					addDishItemVo.setFoodsName(foods.getFoodsName());
					addDishItemVo.setFoodsPrice(foods.getFoodsPrice());
					addDishItemVo.setAddDishItemNum(addDish.getAddDishNum());
					addDishItemVo.setAddDishItemSubtotal(addDish.getAddDishSubtotal());
					addDishItemVo.setFoodsUrl(foods.getFoodsUrl());
					newOrders.getList().add(addDishItemVo);
				}
				
				ordersAndItemsVo.add(newOrders);
			}
		}
		
		
		PageInfo pageInfo = new PageInfo(ordersAndItemsVo);
		return ServerResponse.createBySuccess(pageInfo);
	}

}
